package subject

import (
	"context"
	"encoding/json"
	"fmt"
	"gozero-demo/internal/constants"
	"gozero-demo/internal/model/dao/model"
	"gozero-demo/internal/repo/mysql"
	"gozero-demo/internal/service"
	"gozero-demo/internal/utils"

	"gozero-demo/internal/svc"
	"gozero-demo/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetUserSubjectLogic struct {
	logx.Logger
	ctx         context.Context
	svcCtx      *svc.ServiceContext
	subjectServ *service.SubjectService
	subjectRepo *mysql.SubjectRepo
}

// 获取题目
func NewGetUserSubjectLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserSubjectLogic {
	return &GetUserSubjectLogic{
		Logger:      logx.WithContext(ctx),
		ctx:         ctx,
		svcCtx:      svcCtx,
		subjectServ: service.NewSubjectService(ctx, svcCtx),
		subjectRepo: mysql.NewSubjectRepo(ctx, svcCtx),
	}
}

func (l *GetUserSubjectLogic) GetUserSubject(req *types.GetUserSubjectRequest) (resp *types.CommonResponse, err error) {
	//获取题目全局配置:方式一:不推荐
	//subjectList, err := l.subjectServ.GetSubjectConfig1()
	//if err != nil {
	//	return nil, err
	//}

	//获取题目全局配置:方式二
	//subjectList, err := l.subjectServ.GetSubjectConfig2()
	//if err != nil {
	//	return nil, err
	//}

	subjectList := l.subjectServ.GetSubjectConfig3()

	// 创建深拷贝(由于subjectList是个切片,是个引用类型,因此需要使用DeepCopy函数进行深拷贝)
	subjectList = l.DeepCopy(subjectList)

	//返回给前端的结构
	resultData := &types.GetUserSubjectResponse{
		UserId:       req.UserId,
		SubjectCount: 0,
		SubjectList:  subjectList,
	}

	//校验当前数据是否存在
	existInfo, err := l.subjectRepo.GetSubjectInfoByUserId(req.UserId)
	if err != nil {
		return nil, err
	}
	if existInfo == nil {
		return nil, constants.DataNotFound
	}
	if len(existInfo.SubjectData) == 0 || existInfo.SubjectData == "{}" || existInfo.SubjectData == "[]" {
		return types.SuccessResponse(resultData, l.ctx), nil
	}

	//将existInfo.SubjectData 解析为结构体
	var existSubjectData model.SubjectDataList
	err = json.Unmarshal([]byte(existInfo.SubjectData), &existSubjectData)
	if err != nil {
		logx.Errorf("json.Unmarshal err: %v", err)
		return nil, err
	}
	fmt.Println("existSubjectData:", utils.EchoJson(existSubjectData))

	//递归处理,将 existSubjectData 中的指定数据赋值到 subjectList
	fmt.Println("subjectList递归前:", utils.EchoJson(subjectList))
	subjectList = l.RecursionGetValue(subjectList, existSubjectData)
	fmt.Println("subjectList递归后:", utils.EchoJson(subjectList))

	//返回给前端的结构
	resultData.SubjectList = subjectList
	return types.SuccessResponse(resultData, l.ctx), nil
}

// RecursionGetValue 递归处理,将 existSubjectData 中的指定数据赋值到 subjectList
func (l *GetUserSubjectLogic) RecursionGetValue(subjectList []types.SubjectData, existSubjectData model.SubjectDataList) []types.SubjectData {
	for i := range subjectList {
		for j := range existSubjectData {
			if subjectList[i].SubjectNumber == existSubjectData[j].SubjectNumber {
				// 递归的将用户的 答题答案 赋值到 subjectList(题库模板中)
				subjectList[i].SubjectAnswer = existSubjectData[j].SubjectAnswer
				l.RecursionGetValue(subjectList[i].Children, existSubjectData[j].Children)
				// 当前节点的子节点都处理完后，跳出循环
				if len(subjectList[i].Children) == 0 {
					break
				}
			}
		}
	}
	return subjectList
}

// DeepCopy 深拷贝 []types.SubjectData
func (l *GetUserSubjectLogic) DeepCopy(stageList []types.SubjectData) []types.SubjectData {
	result := make([]types.SubjectData, len(stageList))
	for i, item := range stageList {
		result[i] = item
		if item.Children != nil {
			result[i].Children = l.DeepCopy(item.Children)
		}
	}
	return result
}
